package com.bsoft.ecommerce.service.async;

import com.alibaba.fastjson.JSON;
import com.bsoft.ecommerce.constant.GoodsConstant;
import com.bsoft.ecommerce.dao.EcommerceGoodsDao;
import com.bsoft.ecommerce.entity.EcommerceGoods;
import com.bsoft.ecommerce.goods.GoodsInfo;
import com.bsoft.ecommerce.goods.SimpleGoodsInfo;
import io.swagger.annotations.Authorization;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.lang3.time.StopWatch;
import org.apache.kafka.common.protocol.types.Field;
import org.aspectj.lang.annotation.AfterThrowing;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
@Transactional
public class AsynServiceImpl implements IAsynService {
    @Autowired
    private EcommerceGoodsDao ecommerceGoodsDao;
    @Autowired
    private RedisTemplate redisTemplate;

    @Async("getAsyncExecutor")
    @Override
    public void asynImportGoods(List<GoodsInfo> goodsInfos, String taskId) {
        log.info("task 执行", taskId);

        StopWatch watch = StopWatch.createStarted();
        //存在重复的商品不保存
        //请求数据是否合法的标记
        boolean isIlleage = false;
        //用来判断是否重复

        Set<String> goodsJointInfos = new HashSet<>(goodsInfos.size());

        //可以入库的 安装自己的业务需求
        List<GoodsInfo> filterGoodsInfo = new ArrayList<>(goodsInfos.size());
        //循环 过滤非法参数
        for (GoodsInfo goods : goodsInfos) {
            //基本条件不满足
            if (goods.getPrince() <= 0 || goods.getSupply() <= 0) {
                continue;
            }
            String jointInfo = String.format("%s,%s,%s", goods.getGoodsCategory(), goods.getBrandCategory(), goods.getGoodsName());
            if (goodsJointInfos.contains(jointInfo)) {
                isIlleage = true;
            }
            //加入容器中
            goodsJointInfos.add(jointInfo);
            filterGoodsInfo.add(goods);
        }
        //如果存在重复商品或者入库的商品
        if (isIlleage || CollectionUtils.isEmpty(filterGoodsInfo)) {
            watch.stop();
            log.info("---", watch.getTime(TimeUnit.MICROSECONDS));

            return;
        }
        List<EcommerceGoods> ecommerceGoods = filterGoodsInfo.stream()
                .map(EcommerceGoods::to).collect(Collectors.toList());

        List<EcommerceGoods> targetGoods = new ArrayList<>(ecommerceGoods.size());
        //先判断是否存在
        ecommerceGoods.forEach(g -> {
            if (null != ecommerceGoodsDao.findFirst1ByGoodsCategoryAndBrandCategoryAndGoodsName(g.getGoodsCategory(), g.getBrandCategory(), g.getGoodsName()).orElse(null)) {
                return;
            }
            targetGoods.add(g);
        });
        //商品信息入库
        List<EcommerceGoods> saveGoods = IterableUtils.toList(
                ecommerceGoodsDao.saveAll(targetGoods)
        );
        //将入库信息同步到 redis
        saveNewGoodsInfoToRedis(saveGoods);
        log.info("good info ");
        watch.stop();
        log.info("", watch.getTime(TimeUnit.MICROSECONDS));
    }

    //redis
    private void saveNewGoodsInfoToRedis(List<EcommerceGoods> saveGoods) {
        List<SimpleGoodsInfo> simpleGoodsInfos = saveGoods.stream().map(EcommerceGoods::toSimple).collect(Collectors.toList());
        Map<String, String> idJsonObject = new HashMap<>(simpleGoodsInfos.size());
        simpleGoodsInfos.forEach(g -> idJsonObject.put(g.getId().toString(), JSON.toJSONString(g)));

        redisTemplate.opsForHash().putAll(
                GoodsConstant.ECOMMERCE_GOODS_DICT_KEY, idJsonObject

        );
    }
}
